package com.liy.framework.web.spring.exception;

import com.liy.framework.common.exception.ApiParamValidatorException;
import com.liy.framework.common.exception.BusinessException;
import com.liy.framework.common.exception.NotAuthorizationException;
import com.liy.framework.common.exception.NotPermissionException;
import com.liy.framework.common.extvo.ResponseVo;
import com.liy.framework.common.extvo.ResultVO;
import org.springframework.context.*;
import org.springframework.beans.factory.annotation.*;
import javax.servlet.http.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.web.servlet.*;
import javax.servlet.*;
import org.springframework.web.bind.annotation.*;
import io.jsonwebtoken.*;
import org.springframework.http.*;
import javax.validation.*;
import java.util.*;

@ControllerAdvice
public class GlobalExceptionHandler
{
    @Autowired
    MessageSource messageSource;

    @ExceptionHandler({ Exception.class })
    public Object defaultErrorHandler(final HttpServletRequest request, final HttpServletResponse response, final Exception e) throws Exception {
        final String accept = request.getHeader("Accept");
        final boolean ajax = true;
        if (ajax || accept == null || accept.contains("json")) {
            final ResultVO resultVO = new ResultVO(false);
            resultVO.setMessage(e.getMessage());
            resultVO.put("status", (Object)this.getStatus(request).value());
            resultVO.put("path", (Object)request.getRequestURL().toString());
            resultVO.put("timestamp", (Object)System.currentTimeMillis());
            response.flushBuffer();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            final ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(new ObjectMapper().writeValueAsString((Object)resultVO).getBytes("UTF-8"));
            outputStream.flush();
            return null;
        }
        final ModelAndView view = new ModelAndView();
        view.addObject("message", (Object)e.getMessage());
        view.addObject("success", (Object)false);
        view.addObject("status", (Object)this.getStatus(request).value());
        view.addObject("path", (Object)request.getRequestURL());
        view.addObject("timestamp", (Object)System.currentTimeMillis());
        view.setViewName("error");
        return view;
    }

    @ExceptionHandler({ BusinessException.class })
    @ResponseBody
    public ResultVO jsonErrorHandler(final HttpServletRequest request, final BusinessException e) throws Exception {
        final ResultVO resultVO = new ResultVO(false);
        resultVO.setMessage(e.getMessage());
        resultVO.put("status", (Object)this.getStatus(request).value());
        resultVO.put("path", (Object)request.getRequestURL());
        resultVO.put("timestamp", (Object)System.currentTimeMillis());
        return resultVO;
    }

    @ExceptionHandler({ MalformedJwtException.class })
    @ResponseBody
    public ResultVO jwtTokenErrorHandler(final HttpServletRequest request, final MalformedJwtException e) throws Exception {
        final ResultVO resultVO = new ResultVO(false);
        resultVO.setMessage("\u975e\u6cd5\u7684\u8ba4\u8bc1\u8bf7\u6c42");
        resultVO.put("status", (Object)"401");
        resultVO.put("path", (Object)request.getRequestURL());
        resultVO.put("timestamp", (Object)System.currentTimeMillis());
        return resultVO;
    }

    @ExceptionHandler({ ApiParamValidatorException.class })
    @ResponseBody
    public ResponseVo apiParamValidatorExceptionHandler(final HttpServletRequest request, final ApiParamValidatorException e) throws Exception {
        return ResponseVo.error(e.getCode(), e.getMessage());
    }

    @ExceptionHandler({ NotPermissionException.class })
    @ResponseBody
    public ResultVO noPermissionExceptionExceptionHandler(final HttpServletRequest request, final NotPermissionException e) throws Exception {
        final ResultVO resultVO = new ResultVO(false);
        resultVO.setMessage(e.getMessage());
        resultVO.put("status", (Object)HttpStatus.FORBIDDEN.toString());
        resultVO.put("path", (Object)request.getRequestURL());
        resultVO.put("timestamp", (Object)System.currentTimeMillis());
        return resultVO;
    }

    @ExceptionHandler({ NotAuthorizationException.class })
    @ResponseBody
    public ResultVO noAuthorizationExceptionHandler(final HttpServletRequest request, final NotAuthorizationException e) throws Exception {
        final ResultVO resultVO = new ResultVO(false);
        resultVO.setMessage(e.getMessage());
        resultVO.put("status", (Object)HttpStatus.UNAUTHORIZED.toString());
        resultVO.put("path", (Object)request.getRequestURL());
        resultVO.put("timestamp", (Object)System.currentTimeMillis());
        return resultVO;
    }

    protected HttpStatus getStatus(final HttpServletRequest request) {
        final Integer statusCode = (Integer)request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        try {
            return HttpStatus.valueOf((int)statusCode);
        }
        catch (Exception ex) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
    }

    @ExceptionHandler({ ConstraintViolationException.class })
    @ResponseBody
    public ResultVO handleResourceNotFoundException(final ConstraintViolationException e) {
        final ResultVO resultVO = new ResultVO(false);
        final Set<ConstraintViolation<?>> violations = (Set<ConstraintViolation<?>>)e.getConstraintViolations();
        final StringBuilder strBuilder = new StringBuilder();
        for (final ConstraintViolation<?> violation : violations) {
            final String str = violation.getPropertyPath().toString();
            strBuilder.append(str.substring(str.lastIndexOf(".") + 1)).append(":").append(violation.getMessage()).append(";");
        }
        resultVO.setStatus(HttpStatus.PRECONDITION_FAILED.toString());
        resultVO.setMessage(strBuilder.toString());
        return resultVO;
    }
}
